#include <stdio.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "hi_io.h"
#include "hi_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_uart.h"
#include <hi_stdlib.h>
#include "lock_property.h"
#include "face_charateristic.h"
#include "iot_watchdog.h"

#define LOCK_CONTROL  3
#define LOCK_CHECK    5


lock_class_t door_lock[1];

/**************************Handler face***************************/
void SetFaceHandler(uint32_t (*handler)(char *));
FaceCharacteristic_t face_charateristic;
void _MsgHandler(char * msg)
{
    for(int i = 0; i < 4; i++)
    {
        face_charateristic.byte[i] = msg[3-i];
    }
    printf("%x\n",face_charateristic.Recognize);
    
    switch(face_charateristic.Recognize)
    {
        case Hzh_Face: 
                    printf("Hzh\n");
                    door_lock[0].operation = LOCK_OPERATION_UNLOCK;
                    break;
        case Wjm_Face: 
                    printf("Wjm\n");
                    door_lock[0].operation = LOCK_OPERATION_LOCK;
                    break;
        case BackGround_B: 
                    printf("Back\n");
                    door_lock[0].operation = LOCK_OPERATION_LOCK;break;
        default:   
                    printf("Def\n");
                    door_lock[0].operation = LOCK_OPERATION_LOCK;
                    break;
    }
    face_charateristic.Recognize = 0;
}
/***************************************************************/


uint32_t handler_lock_lock(lock_class_t *lock_class)
{
    printf("lock triggered\n");
    IoTGpioSetOutputVal(lock_class->control, 0);
    IoTGpioSetOutputVal(9,1); //Lighting-off
    return 0;
}

uint32_t handler_lock_unlock(lock_class_t *lock_class)
{
    printf("unlock triggered\n");
    IoTGpioSetOutputVal(lock_class->control, 1);
    IoTGpioSetOutputVal(9,0); //Lighting-on
    return 0;
}

void LockActingHandler(void)
{
    door_lock[0].operation = LOCK_OPERATION_LOCK;
}

void GPIO_Init(void)
{
    for(int i = 0; i < 1; i++)
    {
    IoTGpioInit(door_lock[0].check);
    IoSetFunc(door_lock[0].check, 0);//Set to GPIO
    IoTGpioSetDir(door_lock[0].check, IOT_GPIO_DIR_IN);
    IoSetPull(door_lock[0].check, IOT_IO_PULL_UP);
    IoTGpioRegisterIsrFunc(door_lock[0].check, \
                            IOT_INT_TYPE_EDGE,IOT_GPIO_EDGE_FALL_LEVEL_LOW, \
                            NULL /*Handler*/, NULL);
    IoTGpioInit(door_lock[0].control);
    IoSetFunc(door_lock[0].control, 0); // Set to GPIO
    IoTGpioSetDir(door_lock[0].control, IOT_GPIO_DIR_OUT);
    IoTGpioSetOutputVal(door_lock[0].control, 0);
    }

    //LED_Init
    IoTGpioInit(9);
    IoSetFunc(9,0);
    IoTGpioSetDir(9, IOT_GPIO_DIR_OUT);
    IoTGpioSetOutputVal(9, 1); //lighting-off
}

static __attribute__((used)) void *lock_control_task(void)
{
    while(1)
    {
        switch(door_lock[0].status)
        {
            case LOCK_STATUS_UNLOCK: usleep(1000000);
                                     door_lock[0].operation = LOCK_OPERATION_LOCK;
                                     break;
            default :break;
        }
        switch(door_lock[0].operation)
        {
            case LOCK_OPERATION_UNLOCK:
                    printf("case unlock\n");
                    door_lock[0].unlock(&door_lock[0]); 
                    door_lock[0].operation = LOCK_OPERATION_NO;
                    door_lock[0].status    = LOCK_STATUS_UNLOCK;
                    break;
            case LOCK_OPERATION_LOCK  :
                    printf("case lock\n");
                    door_lock[0].lock(&door_lock[0]);
                    door_lock[0].operation = LOCK_OPERATION_NO;
                    door_lock[0].status    = LOCK_STATUS_LOCKED;
                    break;
            default :break;
        }
        printf("x");
    }
}

static void start_LockEvent_Task(void)
{
    osThreadAttr_t attr=
    {
        .name = "lock_control_task",
        .attr_bits = 0U,
        .cb_mem = NULL,
        .cb_size = 0U,
        .stack_mem = NULL,
        .stack_size = 1024,
        .priority   = osPriorityNormal,
    };
    door_lock[0].check     = 11;
    door_lock[0].control   = 12;
    door_lock[0].status    = LOCK_STATUS_LOCKED;
    door_lock[0].operation = LOCK_OPERATION_NO;
    door_lock[0].lock      = handler_lock_lock;
    door_lock[0].unlock    = handler_lock_unlock;
    GPIO_Init();

    SetFaceHandler(_MsgHandler);
    for(int i=0; i < 1; i++)
    {
        door_lock[i].lock   = handler_lock_lock;
        door_lock[i].unlock = handler_lock_unlock;
    }
    IoTWatchDogDisable();
    if(osThreadNew((osThreadFunc_t)lock_control_task, NULL, &attr) == NULL)
    {
        printf("Task \"%s\" faild to start\n",attr.name);
    }
}

SYS_RUN(start_LockEvent_Task);